#include <my_header.h>
#include "threadPool.h"

#define MAX_CONNECT_NUM 1024
//从conf文件中读入的参数的最大的个数
#define MAX_CONF_VECTOR_NUM 10
//conf文件中应该读入的参数的个数
#define CONF_VECTOR_COUNT 3
/* Usage: 客户端 */
int exitPipe[2];//用于进程通信的管道
void sigHandler(int sig){
    printf("recived signal:%d!\n",sig);
    write(exitPipe[1],"1",1);//向管道中写入信息
}
// 切分输入为命令和参数
int split_input(char *input, char *delimiter, char *parts[]) {
    char *save_state_strtok_r;
    char *token = strtok_r(input, delimiter, &save_state_strtok_r);
    int count = 0;

    while (token != NULL) {
        // 找到 ':' 的位置
        char *colon_pos = strchr(token, ':');
        if (colon_pos != NULL) {
            // 提取 ':' 后面的部分
            parts[count++] = colon_pos + 1;
        }
        token = strtok_r(NULL, delimiter, &save_state_strtok_r);
    }

    return count;
}

int read_conf(char* conf_path,char* confv[]){
    int confFd = open(conf_path,O_RDONLY);
    ERROR_CHECK(confFd,-1,"open conf:");
    char contant[4096] = {0};
    read(confFd,contant,sizeof(contant));
    /* printf("%s\n",contant); */
    int count = split_input(contant,"\n",confv);
    return count;
}
//2.0两个进程，异步拉起同步
int main(int argc, char *argv[]){                                  
    // ./NetDiskServer ../conf/server.conf
    ARGS_CHECK(argc,2);

    char *confv[MAX_CONF_VECTOR_NUM];
    int conf_parameter_count = read_conf(argv[1],confv);
    if(conf_parameter_count != 3){
        /* printf("conf file error\n"); */
        exit(0);
    }
    pipe(exitPipe);//exitPipe[0]是读端,exitPipe[1]是写端
    if(fork()){
        //父进程
        close(exitPipe[0]);//父进程关闭读端
        signal(SIGUSR1,sigHandler);
        wait(NULL);//等待子进程退出
        printf("Parent is going to die\n");
        exit(0);
    }
    //能走到这一定是子进程
    close(exitPipe[1]);//子进程关闭写端
    int sockfd = tcpInit(confv[0],confv[1]);
    /* printf("sockfd : %d\n",sockfd); */
    int epfd = epoll_create(1);
    epollAdd(epfd,sockfd);
    epollAdd(epfd,exitPipe[0]);//把管道的读端加入监听
    struct epoll_event readySet[MAX_CONNECT_NUM];

    threadPool_t pThreadPool;
    threadPoolInit(&pThreadPool,atoi(confv[2]));
    makeWorker(&pThreadPool,atoi(confv[2]));

    while(1){
        int readyNum = epoll_wait(epfd,readySet,MAX_CONNECT_NUM,-1);
        for(int i=0;i<readyNum;i++){
            if(readySet[i].data.fd == sockfd){
                int netfd = accept(sockfd,NULL,NULL);
                pthread_mutex_lock(&pThreadPool.mutex);
                enQueue(&pThreadPool.pTaskQueue,netfd);
                pthread_cond_broadcast(&pThreadPool.cond);
                pthread_mutex_unlock(&pThreadPool.mutex);
            }else if(readySet[i].data.fd == exitPipe[0]){
                printf("child is going to die\n");
                //父进程通知子进程结束
                pthread_mutex_lock(&pThreadPool.mutex);
                //改退出标志位，因为这是一个共享资源，所以在改之前要上锁
                pThreadPool.exit_flag = 1;
                pthread_cond_broadcast(&pThreadPool.cond);
                pthread_mutex_unlock(&pThreadPool.mutex);
                //等待子进程退出
                for(int i=0;i<pThreadPool.pTidArr.size;i++){
                    pthread_join(pThreadPool.pTidArr.pArr[i],NULL);
                }
                printf("child has died\n");
                exit(0);
            }
        }
    }
    return 0;
}
